package com.kiwi.util.EncryptSet.Constant;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * <p>Title: NUSP</p>
 * <p>Description: NetEase Uniq Subscribe Platform</p>
 * <p>Copyright: Copyright (c) 2009</p>
 * <p>Company: NetEase Corp.</p>
 * @author Sunfine
 * @version 1.0
 */

public class AES {

	private static final String MYKEY = "10661630";
	private final static String type = "AES";

	public static void main(String[] args){
		try{
			String k1 = "9A22802D9826D40A0AB6DEC5D23C63AD";//为每一个自己验证的newegg
			String k2 = "54EFA92D090ABCAF44B071D1E3C31F39";//URS验证的程序本地
			String k3 = "FB1A4A014C42D8C774725331BF0BF3D4";//用户名
			String k4 = "FA49FF7358B5AB417F1EB7E47D1401AB";//URS配置
			String key = createKey();
//			String key = k4;
			System.out.println("key:"+key);
			
			String r_url = java.net.URLEncoder.encode("http://reg.163.com/test.jsp", "utf-8");
			String username = "2C2D2175DC606E0322D615F9352464D1";
			String ts = "20100311110301";
			StringBuffer src = new StringBuffer();
	        src.append(username).append(ts).append(r_url);
	        
	        String sign = AES.byte2hex(AES.encrypt(src.toString().getBytes("utf-8"), AES.hex2byte(key)));
//	        String l = "7406736A41D98EAA21479772042592" +
//	        		"177F122C5BC3AE7C7676BFB088CBB55CDB40C832FC" +
//	        		"B4810A496672F947D0F3236D2D469BB1316737CA71BB243AE8773EE" +
//	        		"6BF13C7686A9FB39B1DCDBADEA0D3D4A2CCBBFFBCBC1BCCA85AFCCBCA40AC3B7D";
	        System.out.println("sign:"+sign);
			
//			String deskey = "993124533F1532C6";
//			String data = "urstest_cbj";
//			byte[] encryData = AES.encrypt(data.getBytes("utf-8"), AES.hex2byte(key));
//			byte[] decryData = AES.decrypt(encryData, AES.hex2byte(key));
//			System.out.println(new String(decryData, "utf-8"));
//			System.out.println("key:"+key);
//			
////			byte[] encryData = DES.encrypt(data.getBytes("utf-8"), AES.hex2byte(key));
//			System.out.println("data.length:"+data.length());
//			System.out.println("encryData.length:"+encryData.length);
//			printByte(encryData);
//			System.out.println("encryted data:"+ AES.byte2hex(encryData));
//			System.out.println(System.getProperty("java.version"));
//            System.out.println(System.getProperty("java.home"));

		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public static void printByte(byte[] b){
		for(byte i : b){
			System.out.print(i+" ");
		}
		System.out.println();
	}
	
	/**
	 * 生成一个AES的密钥
	 * @return
	 */
	public static String createKey(){
		try{
			KeyGenerator kg = KeyGenerator.getInstance("AES"); // 获取密匙生成器 
			kg.init(128); // 初始化
			// DES算法必须是56位
			// DESede算法可以是112位或168位
			// AES算法可以是128、192、256位 
			SecretKey key = kg.generateKey(); // 生成密匙，可用多种方法来保存密匙
			byte[] keyByte = key.getEncoded();
			return byte2hex(keyByte);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 加密
	 * @param src 数据源
	 * @param key 密钥，长度必须是8的倍数
	 * @return  返回加密后的数据
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] src, byte[] kv)throws Exception
	{
		SecretKey key = new SecretKeySpec(kv, "AES");
		
		long start = System.currentTimeMillis();
		//加密：
		Cipher cp = Cipher.getInstance("AES"); // 创建密码器 
		cp.init(Cipher.ENCRYPT_MODE, key); // 初始化
		byte[] ctext = cp.doFinal(src); // 加密
		return ctext;
	}

	/**
	 * 解密
	 * @param src 数据源
	 * @param key 密钥，长度必须是8的倍数
	 * @return   返回解密后的原始数据
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] src, byte[] kv)throws Exception
	{
		SecretKey key = new SecretKeySpec(kv, "AES");
		Cipher cp = Cipher.getInstance("AES"); // 创建密码器 
		cp.init(Cipher.DECRYPT_MODE, key); // 初始化
		byte[] ptext = cp.doFinal(src); // 解密 
		return ptext;
	}

	/**
	 * 密码解密
	 * @param data
	 * @param key 只取8位
	 * @return
	 * @throws Exception
	 */
	public final static String decrypt(String data, String key)
	{
		if(key==null||key.trim().length()==0) key=MYKEY;
		if(key.length()>8) key=key.substring(0,8);
		try {
			return new String(decrypt(hex2byte(data), key.getBytes()));
		} catch(Exception e) {}
		return "";
	}

	/**
	 * 密码加密
	 * @param password
	 * @param key 只取8位
	 * @return
	 * @throws Exception
	 */
	public final static String encrypt(String password, String key)
	{

		if(key==null||key.trim().length()==0) key=MYKEY;
		if (key.length() > 16)
		{
			key = key.substring(0, 16);//FIXME
		}
		try {
			return byte2hex(encrypt(password.getBytes(),key.getBytes()));
		} catch(Exception e) {		System.out.println("%%%%"+e);}
		return "";
	}

	/**
	 * 数组转十六进制字符串
	 * @param b
	 * @return
	 */
	public static String byte2hex(byte[] b)
	{
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs.toUpperCase();
	}

	/**
	 * 十六进制字符串转数组
	 * @param b
	 * @return
	 */
	public static byte[] hex2byte(String s)
	{
		byte[] b=s.getBytes();
		if((b.length%2)!=0)
			throw new IllegalArgumentException("长度不是偶数");
		byte[] b2 = new byte[b.length/2];
		for (int n = 0; n < b.length; n+=2) {
			String item = new String(b,n,2);
			b2[n/2] = (byte)Integer.parseInt(item,16);
		}
		return b2;
	}

	public static String byte2lowHex(byte[] b)
	{
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs.toLowerCase();
	}

	public static String convertBase64ToHex(String base64Str){
		try{
			BASE64Decoder base64decoder = new BASE64Decoder();
			byte[] byteStr = base64decoder.decodeBuffer(base64Str);	
			String hexStr = byte2lowHex(byteStr);
			return hexStr;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	public static String convertHexToBase64(String hexStr){
		try{
			byte[] byteStr = hex2byte(hexStr);
			BASE64Encoder base64Encoder = new BASE64Encoder();
			String base64Str = base64Encoder.encodeBuffer(byteStr);	
			return base64Str;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

}
